package nirvana.core.domains.vo;

import lombok.Data;

import java.io.Serializable;

/**
 * ApiResult
 *
 * @author linkanyway
 * @version 1.0
 * @date 2023/10/30 21:50
 */
@Data
public class ApiResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * success??
     */
    private boolean success = true;

    /**
     * return code
     */
    private Integer code = 0;

    /**
     * return message
     */
    private String message = "";


    /**
     * return data
     */
    private T data;

    /**
     * timestamp
     */
    private long timestamp = System.currentTimeMillis ();


    /**
     * constructor
     */
    public ApiResult() {
    }

    /**
     * constructor
     *
     * @param code    code
     * @param message message
     */
    public ApiResult(Integer code, String message) {
        this.code = code;
        this.message = message;
    }


    /**
     * generate success api result
     *
     * @param message message
     * @return ApiResult with 200 code
     */
    public ApiResult<T> success(String message) {
        this.message = message;
        this.code = ApiResultConstant.RS_OK;
        this.success = true;
        return this;
    }

    /**
     * generate api result with 200
     *
     * @param <T> type parameter
     * @return api result
     */
    public static <T> ApiResult<T> ok() {
        ApiResult<T> r = new ApiResult<T> ();
        r.setSuccess (true);
        r.setCode (ApiResultConstant.RS_OK);
        return r;
    }

    /**
     * generate api result with 200
     *
     * @param <T> type parameter
     * @param msg message
     * @return api result
     */
    public static <T> ApiResult<T> ok(String msg) {
        ApiResult<T> r = new ApiResult<T> ();
        r.setSuccess (true);
        r.setCode (ApiResultConstant.RS_OK);
        r.setMessage (msg);
        return r;
    }

    /**
     * generate api result with 200
     *
     * @param <T>  type parameter
     * @param data data
     * @return api result
     */
    public static <T> ApiResult<T> ok(T data) {
        ApiResult<T> r = new ApiResult<T> ();
        r.setSuccess (true);
        r.setCode (ApiResultConstant.RS_OK);
        r.setData (data);
        return r;
    }

    /**
     * generate api result with 200
     *
     * @param <T>     type parameter
     * @param data    data
     * @param message message
     * @return api result
     */
    public static <T> ApiResult<T> ok(String message, T data) {
        ApiResult<T> r = new ApiResult<T> ();
        r.setSuccess (true);
        r.setMessage (message);
        r.setCode (ApiResultConstant.RS_OK);
        r.setData (data);
        return r;
    }


    /**
     * Error result
     *
     * @param msg  message
     * @param data data
     * @param <T>  type
     * @return ApiResult
     */
    public static <T> ApiResult<T> error(String msg, T data) {
        ApiResult<T> r = new ApiResult<T> ();
        r.setSuccess (false);
        r.setCode (ApiResultConstant.RS_SERVER_ERROR);
        r.setMessage (msg);
        r.setData (data);
        return r;
    }

    /**
     * Error result
     *
     * @param msg message
     * @param <T> type
     * @return ApiResult
     */
    public static <T> ApiResult<T> error(String msg) {
        return error (ApiResultConstant.RS_SERVER_ERROR, msg);
    }

    /**
     * Error result
     *
     * @param code code
     * @param msg  message
     * @param <T>  type
     * @return ApiResult
     */
    public static <T> ApiResult<T> error(int code, String msg) {
        ApiResult<T> r = new ApiResult<T> ();
        r.setCode (code);
        r.setMessage (msg);
        r.setSuccess (false);
        return r;
    }

    /**
     * no auth
     *
     * @param msg message
     * @param <T> type parameter
     * @return ApiResult
     */
    public static <T> ApiResult<T> noAuth(String msg) {
        return error (ApiResultConstant.RS_NO_AUTH, msg);
    }
}
